#ifndef _IM_SERVER_LINGER_SESSION_MAP_
#define _IM_SERVER_LINGER_SESSION_MAP_

#include <map>
#include <string>
#include <boost/asio.hpp>

#include "http_request.h"
#include "ImServiceCommon_types.h"

namespace imserver {

using boost::asio::deadline_timer;

class LingerSession {
 public:
  LingerSession(int64_t uid, const std::string & session);
  ~LingerSession();

  void AppendMessage(const ImMessage & message) {
    if (buffered_messages_ == NULL) {
      buffered_messages_ = new ImMessageList();
    }
    buffered_messages_->push_back(message);
  }

  ImMessageList * FetchMessages() {
    ImMessageList * ret = NULL;
    if (buffered_messages_ != NULL) {
      ret = buffered_messages_;
      buffered_messages_ = NULL;
    }
    return ret;
  }

  void StartTimer(int64_t uid, const std::string & session);

  void CancelTimer() {
    timer_.cancel();
  }

 private:
  deadline_timer timer_; // uid 和 session记录在timer的callback中
  ImMessageList * buffered_messages_;
};
typedef boost::shared_ptr<LingerSession> LingerSessionPtr;

class LingerSessionMap {
 public:
  static LingerSessionMap & Instance() {
    static LingerSessionMap instance; 
    return instance;
  }
  // 增加linger session
  void Add(int64_t uid, const std::string & session);

  // session 过期
  int Expire(const std::string & session);

  // session 复活
  ImMessageList * Revive(const std::string & session);

  bool BufferMessage(const std::string & session, const ImMessage & message);

  size_t size() const {
    return linger_sessions_.size();
  }
 private:
  LingerSessionMap() {}

  typedef std::map<std::string, LingerSessionPtr> SessionMapType;
  SessionMapType linger_sessions_;
};

}

#endif // _IM_SERVER_LINGER_SESSION_MAP_

